package com.lc1993929.chapter21.cyclicBarrier;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * Created by LiuChang on 2019/1/27
 */
public class HorseRace {
    static final int FINISH_LINE = 75;
    private List<Hourse> hourses = new ArrayList<>();
    private ExecutorService exec = Executors.newCachedThreadPool();
    private CyclicBarrier barrier;

    public HorseRace(int nHourses, final int pause) {
        barrier = new CyclicBarrier(nHourses, () -> {
            StringBuilder s = new StringBuilder();
            for (int i = 0; i < FINISH_LINE; i++) {
                s.append("=");
            }
            System.out.println(s);
            for (Hourse hours : hourses) {
                System.out.println(hours.tracks());
            }
            for (Hourse hours : hourses) {
                if (hours.getStrides() >= FINISH_LINE) {
                    System.out.println(hours + "won!");
                    exec.shutdown();
                    return;
                }
            }
            try {
                TimeUnit.MILLISECONDS.sleep(pause);
            } catch (InterruptedException e) {
                System.out.println("barrier-action sleep interrupted");
            }
        });

        for (int i = 0; i < nHourses; i++) {
            Hourse hourse = new Hourse(barrier);
            hourses.add(hourse);
            exec.execute(hourse);
        }
    }

    public static void main(String[] args) {
        int nhorses = 7;
        int pause = 200;
        if (args.length > 0) {
            int n = new Integer(args[0]);
            nhorses = n > 0 ? n : nhorses;
        }
        if (args.length > 1) {
            int p = new Integer(args[1]);
            pause = p > -1 ? p : pause;
        }
        new HorseRace(nhorses, pause);
    }
}
